package a02;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;

import javax.swing.JPanel;

public class RegularBoard<M> extends JPanel {

    private static final long serialVersionUID = 1L;
    private Color color1 = Color.RED;
    private Color color2 = Color.BLUE;
    private Color colorNone = Color.WHITE;
    private String colorName1 = "ROT";
    private String colorName2 = "BLAU";

    private RegularGame<M> game;
    private int UNIT = 70;
    private boolean blanksActive = false;
    private boolean grid = false;
    private boolean ticTacToeMode;

    public void setTicTacToeMode(boolean ticTacToeMode) {
	this.ticTacToeMode = ticTacToeMode;
    }

    private Graphics2D graphics;
    private Color gridColor;

    public RegularBoard(RegularGame<M> g) {
	this.game = g;
    }

    public RegularGame<M> getGame() {
	return this.game;
    }

    public String getPlayerColorName(byte player) {
	String tmp;
	if (player == this.game.getPlayerOne()) {
	    tmp = colorName1;
	} else if (player == this.game.getPlayerTwo()) {
	    tmp = colorName2;
	} else {
	    tmp = "BLACK";
	}

	return tmp;
    }

    @Override
    public Dimension getPreferredSize() {
	return new Dimension(this.game.getColumns() * this.getUNIT(),
		this.game.getRows() * this.getUNIT());
    }

    public int getUNIT() {
	return UNIT;
    }

    @Override
    public void paintComponent(Graphics g1) {
	
	super.paintComponent(g1);
	
	this.graphics = (Graphics2D) g1;
	
	this.graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
		RenderingHints.VALUE_ANTIALIAS_ON);
	for (byte c = 0; c < this.game.getColumns(); c++) {
	    if (grid && !(c == 0)) {
		 this.graphics.setStroke(new BasicStroke(2, BasicStroke.CAP_SQUARE,
			    BasicStroke.JOIN_MITER));
		this.graphics.setColor(this.gridColor);
		this.graphics.drawLine((c * this.getUNIT()), (0),
			(c * this.getUNIT()),
			(this.game.getRows() * this.getUNIT()));
	    }

	    for (byte r = 0; r < this.game.getRows(); r++) {

		if (isShowBlanksActive()) {
		    if (this.game.getAtPosition(c, r) != this.game
			    .getPlayerNone()) {
			this.graphics.setColor(this.selectColor(this.game
				.getAtPosition(c, r)));
			this.graphics.fillOval((c * this.getUNIT() + 5), (r
				* this.getUNIT() + 5), (this.getUNIT() - 10),
				(this.getUNIT()) - 10);
		    } else if (isShowBlanksActive()
			    && this.game.getAtPosition(c, r) == this.game
				    .getPlayerNone()) {
			this.graphics.setColor(this.getColorNone());
			this.graphics.fillOval((c * this.getUNIT() + 5), (r
				* this.getUNIT() + 5), (this.getUNIT() - 10),
				(this.getUNIT()) - 10);
		    }
		} else {
		    if (!ticTacToeMode
			    && this.game.getAtPosition(c, r) != this.game
				    .getPlayerNone()) {
			this.graphics.setColor(this.selectColor(this.game
				.getAtPosition(c, r)));
			this.graphics.fillOval((c * this.getUNIT()) + 2,
				(r * this.getUNIT()) + 2, (this.getUNIT()) - 4,
				(this.getUNIT()) - 4);
		    } else if (ticTacToeMode
			    && this.game.getAtPosition(c, r) != this.game
				    .getPlayerNone()) {
			this.paintAdvancedStone(c, r);
		    }

		}
	    }
	    
	}
	if (grid) {
	    for (byte r = 1; r < this.game.getRows(); r++) {
		this.graphics.setColor(this.gridColor);
		 this.graphics.setStroke(new BasicStroke(2, BasicStroke.CAP_SQUARE,
			    BasicStroke.JOIN_MITER));
		this.graphics.drawLine(0, (r * this.getUNIT()),
			(this.game.getColumns() * this.getUNIT()),
			(r * this.getUNIT()));
	    }
	}	
    }

    private void paintAdvancedStone(byte c, byte r) {
	if (this.game.getAtPosition(c, r) == this.game.getPlayerOne()) {
	    this.graphics.setColor(this.selectColor(this.game.getAtPosition(c,
		    r)));
	    this.graphics.fillOval((c * this.getUNIT()) + 5,
		    (r * this.getUNIT()) + 5, (this.getUNIT() - 10),
		    (this.getUNIT() - 10));
	    this.graphics.setColor(Color.WHITE);
	    this.graphics.fillOval((c * this.getUNIT() + 16),
		    (r * this.getUNIT() + 16), (this.getUNIT() - 32),
		    (this.getUNIT()) - 32);
	} else if (this.game.getAtPosition(c, r) == this.game.getPlayerTwo()) {

	    this.graphics.setColor(this.selectColor(this.game.getAtPosition(c,
		    r)));
	    this.graphics.setStroke(new BasicStroke(12, BasicStroke.CAP_ROUND,
		    BasicStroke.JOIN_MITER));
	    this.graphics.drawLine((c * this.getUNIT()) + 15,
		    (r * this.getUNIT()) + 15, (c * this.getUNIT()) + 55,
		    (r * this.getUNIT()) + 55);
	    this.graphics.drawLine((c * this.getUNIT()) + 55,
		    (r * this.getUNIT()) + 15, (c * this.getUNIT()) + 15,
		    (r * this.getUNIT()) + 55);
	}
    }

    private Color getColorNone() {
	return this.colorNone;
    }

    public Color selectColor(byte player) {
	Color tmp;
	if (player == this.game.getPlayerOne()) {
	    tmp = this.color1;
	} else if (player == this.game.getPlayerTwo()) {
	    tmp = this.color2;
	} else {
	    tmp = Color.GREEN;
	}
	return tmp;
    }

    public void setPlayerColors(Color color1, String colorName1, Color color2,
	    String colorName2) {
	this.color1 = color1;
	this.colorName1 = colorName1;
	this.color2 = color2;
	this.colorName2 = colorName2;
    }

    public void setGame(RegularGame<M> g) {
	this.game = g;
	this.repaint();
    }

    public void setTableColor(int r, int g, int b) {
	this.setBackground(new Color(r, g, b));
    }

    public void setTableColor(Color c) {
	this.setBackground(c);
    }

    public void setUNIT(int uNIT) {
	UNIT = uNIT;
    }

    public boolean isShowBlanksActive() {
	return blanksActive;
    }

    public void setShowBlanksActive(boolean blanksActive) {
	this.blanksActive = blanksActive;
    }

    public boolean isGridActive() {
	return grid;
    }

    public void setGridActive(boolean grid, Color gridColor) {
	this.grid = grid;
	this.gridColor = gridColor;
    }

}
